﻿
// MFCPlaneWarDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "MFCPlaneWar.h"
#include "MFCPlaneWarDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif



// CMFCPlaneWarDlg 对话框



CMFCPlaneWarDlg::CMFCPlaneWarDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MFCPLANEWAR_DIALOG, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMFCPlaneWarDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BEGIN, m_begin);
	//DDX_Control(pDX, IDC_MARK, m_mark);
}

BEGIN_MESSAGE_MAP(CMFCPlaneWarDlg, CDialogEx)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_CTLCOLOR()
	ON_WM_KEYDOWN()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_TIMER()
	ON_WM_CTLCOLOR()
END_MESSAGE_MAP()


// CMFCPlaneWarDlg 消息处理程序

BOOL CMFCPlaneWarDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标


	// TODO: 在此添加额外的初始化代码

	//设置窗口大小
	MoveWindow(0, 0, 600, 800);

	//设置窗口背景
	CDialogEx::SetBackgroundImage(IDB_BITMAP_BRACK);

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CMFCPlaneWarDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
		srand((unsigned)time(NULL));//第一次打印飞机的位置
		PrintPlaneImage(plane.m_x, plane.m_y, 1);
		SetTimer(1, 200, NULL);//设置定时钟，定时刷新
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFCPlaneWarDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

//获取键盘输入
BOOL CMFCPlaneWarDlg::PreTranslateMessage(MSG* pMsg)
{
	// TODO: 在此添加专用代码和/或调用基类
	if (mousemode == 0)//如果鼠标拖拽，则不能使用键盘
	{
		if (pMsg->message == WM_KEYDOWN)
		{
			SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
		}
	}
	return  FALSE;
	//return CDialogEx::PreTranslateMessage(pMsg);
}
//执行输入按键
void CMFCPlaneWarDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	if (VK_LEFT == nChar)
	{
		if (plane.m_x - 4 <= 650 && plane.m_x - 4 >= -50)
		{
			plane.m_x -= 4;
		}
	}
	if (VK_RIGHT == nChar)
	{
		if (plane.m_x + 4 <= 530 && plane.m_x + 4 >= -50)
		{
			plane.m_x += 4;
		}
	}
	if (VK_DOWN == nChar)
	{
		if (plane.m_y + 4 <= 700 && plane.m_y + 4 >= -50)
		{
			plane.m_y += 4;
		}
	}
	if (VK_UP == nChar)
	{
		if (plane.m_y - 4 <= 746 && plane.m_y - 4 >= -50)
		{
			plane.m_y -= 4;
		}
	}
	if (VK_SPACE == nChar)//按空格开始游戏
	{
		if (fire == 0)
		{
			fire = 1;
			plane.life = true;
			m_begin.ShowWindow(SW_HIDE);
		}
	}
	CDialogEx::OnKeyDown(nChar, nRepCnt, nFlags);
}

// 判断并打印飞机图片（飞机分敌机和自己的飞机）
void CMFCPlaneWarDlg::PrintPlaneImage(int x, int y, int numPlane)
{
	// TODO: 在此处添加实现代码.
	CClientDC dc(this);
	CDC image;
	image.CreateCompatibleDC(&dc);
	CBitmap bmpPlane;
	bmpPlane.LoadBitmap(IDB_BITMAP_AIRPLANE);
	image.SelectObject(bmpPlane);
	if (numPlane == 1)//传入的飞机种类为1则打印自己的飞机
	{
		dc.BitBlt(x, y, 100, 100, &image, (numPlane - 1) * 100, 100, SRCAND);
		dc.BitBlt(x, y, 100, 100, &image, (numPlane - 1) * 100, 0, SRCPAINT);//图片双绘
	}
	if (numPlane == 2 || numPlane == 3)
	{
		dc.BitBlt(x, y, 100, 100, &image, (numPlane - 1) * 100, 0, SRCAND);
		dc.BitBlt(x, y, 100, 100, &image, (numPlane - 1) * 100, 100, SRCPAINT);//图片透明化处理
	}
	image.DeleteDC();
}

// 打印子弹图片
void CMFCPlaneWarDlg::PrintBullteImage(int b_x, int b_y, int numBullte)
{
	// TODO: 在此处添加实现代码.
	CClientDC dc(this);
	CDC image;
	image.CreateCompatibleDC(&dc);
	CBitmap bmp;
	bmp.LoadBitmap(IDB_BITMAP_BULLET);
	image.SelectObject(bmp);
	if (numBullte == 1)//自己飞机的子弹
	{
		dc.BitBlt(b_x, b_y, 25, 25, &image, 0, 25, SRCAND);
		dc.BitBlt(b_x, b_y, 25, 25, &image, 0, 0, SRCPAINT);
	}
	else
	{
		dc.BitBlt(b_x, b_y, 25, 25, &image, 25, 25, SRCAND);
		dc.BitBlt(b_x, b_y, 25, 25, &image, 25, 0, SRCPAINT);
	}
	image.DeleteDC();
}
//鼠标点击
void CMFCPlaneWarDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mousemode == 0)
	{
		mousemode = 1;//第一次点下改为1
	}
	else
	{
		mousemode = 0;//第二次点下改为0
	}

	CDialogEx::OnLButtonDown(nFlags, point);
}
//鼠标拖拽移动
void CMFCPlaneWarDlg::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (mousemode == 1)
	{
		if (plane.m_x <= point.x && plane.m_x + 100 >= point.x)
		{
			if (plane.m_y <= point.y && plane.m_y + 100 >= point.y)//判断鼠标是否在自己飞机上
			{
				if (point.x - 50 <= 490 && point.x - 50 >= 0)
				{
					if (point.y - 50 <= 790 && point.y >= 0)
					{
						plane.m_x = point.x - 50;
						plane.m_y = point.y - 50;//若在且拖拽，把鼠标坐标传给自己飞机的坐标
					}
				}
			}
		}
	}
	CDialogEx::OnMouseMove(nFlags, point);
}

//定时刷新界面
void CMFCPlaneWarDlg::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (plane.life == true)
	{
		if (nIDEvent == 1)
		{
			RedrawWindow(CRect(0, 0, 600, 800));//重绘游戏界面
			SetEnemy();//创建敌机
			PrintPlaneImage(plane.m_x, plane.m_y, 1);//打印飞机
			OpenFire();//判断是否开火
			GetShot();//判断是否中弹
		}
	}
	CDialogEx::OnTimer(nIDEvent);
}


// 创建敌机
void CMFCPlaneWarDlg::SetEnemy()
{
	// TODO: 在此处添加实现代码.
	for (int i = 0; i < ENEMY; i++)
	{
		if (enemy[i].life == false)//是否存活
		{
			enemy[i].life = true;
			enemy[i].e_x = rand() % 500;//x坐标随机赋值
			enemy[i].e_y = 0;
			enemy[i].numPlane = rand() % 2 + 2;//敌机种类随机赋值
		}
		if (enemy[i].life == true)
		{
			enemy[i].e_x += (rand() % 8 - 3);
			enemy[i].e_y += 8;//坐标移动
			PrintPlaneImage(enemy[i].e_x, enemy[i].e_y, enemy[i].numPlane);//移动后再次打印
			for (int j = 0; j < ENEMYBULLTE; j++)
			{
				if (enemy[i].bullte[j].life == false)
				{
					enemy[i].bullte[j].life = true;
					enemy[i].bullte[j].b_x = enemy[i].e_x + 38;
					enemy[i].bullte[j].b_y = enemy[i].e_y + 100;//创建出敌机的子弹
					break;
				}
			}
		}
		if (enemy[i].e_y > 800)//超出游戏界面则删除敌机
		{
			enemy[i].life = false;
		}
	}
	for (int i = 0; i < ENEMY; i++)//让子弹向下移动
	{
		for (int j = 0; j < ENEMYBULLTE; j++)
		{
			if (enemy[i].bullte[j].life == true)
			{
				enemy[i].bullte[j].b_y += 25;
				PrintBullteImage(enemy[i].bullte[j].b_x, enemy[i].bullte[j].b_y, enemy[i].numPlane);//打印
			}
			if (enemy[i].bullte[j].b_y > 800)//是否超出游戏界面
			{
				enemy[i].bullte[j].life = false;
			}
		}
	}
}


// 判断敌机中弹
void CMFCPlaneWarDlg::GetShot()
{
	// TODO: 在此处添加实现代码.
	for (int i = 0; i < ENEMY; i++)
	{
		for (int j = 0; j < PLANEBULLTE; j++)
		{
			if (plane.bullte[j].life == true)
			{
				if (enemy[i].e_x <= plane.bullte[j].b_x + 15 && enemy[i].e_x + 100 >= plane.bullte[j].b_x + 15)
				{
					if (enemy[i].e_y <= plane.bullte[j].b_y + 15 && enemy[i].e_y + 100 >= plane.bullte[j].b_y + 15)
					{
						enemy[i].life = false;
						plane.bullte[j].life = false;//若中弹则删除敌机和子弹
						mark += 5;

					}
				}
			}
		}
		for (int j = 0; j < ENEMY; j++)//判断自己是否中弹
		{
			if (enemy[i].bullte[j].life == true)
			{
				if (plane.m_x <= enemy[i].bullte[j].b_x + 15 && plane.m_x + 100 >= enemy[i].bullte[j].b_x + 15)
				{
					if (plane.m_y <= enemy[i].bullte[j].b_y + 15 && plane.m_y + 100 >= enemy[i].bullte[j].b_y + 15)
					{
						plane.life = false;
						MessageBox(_T("中弹, 死亡！"));//消息提示框
					}
				}
			}
		}
	}
}


// 是否开火
void CMFCPlaneWarDlg::OpenFire()
{
	// TODO: 在此处添加实现代码.
	if (fire == 1)//游戏开始
	{
		for (int j = 0; j < PLANEBULLTE; j++)
		{
			if (plane.bullte[j].life == false)
			{
				plane.bullte[j].life = true;
				plane.bullte[j].b_x = plane.m_x + 38;
				plane.bullte[j].b_y = plane.m_y;
				break;
			}
		}
	}
	for (int j = 0; j < PLANEBULLTE; j++)
	{
		if (plane.bullte[j].b_y <= 0 && plane.bullte[j].life == true)
		{
			plane.bullte[j].life = false;
		}
		plane.bullte[j].b_y -= 25;
		PrintBullteImage(plane.bullte[j].b_x, plane.bullte[j].b_y, 1);
	}
}
//设置开始提示消息的文本颜色
HBRUSH CMFCPlaneWarDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  在此更改 DC 的任何特性
	switch (pWnd->GetDlgCtrlID())
	{
	case IDC_BEGIN:
		pDC->SetTextColor(RGB(255, 128, 0));
		pDC->SetBkMode(TRANSPARENT);
		break;
	}

	// TODO:  如果默认的不是所需画笔，则返回另一个画笔
	return hbr;
}



